// filepath: e:\BaiduSyncdisk\课业文件\DSAA5024数据探索与可视化\homework\project\mv_bike\src\services\api.ts
const API_BASE_URL = 'http://127.0.0.1:8000/api/v1';

// --- 类型定义 ---
export interface CommunityGeo {
  type: 'Feature';
  geometry: any;
  properties: {
    id: number;
    name: string;
    district: string;
  };
}

export interface HistoricalFlow {
  community_id: number;
  time_slot: string;
  net_flow: number;
}

export interface PredictedFlowPoint {
  time_slot: string;
  predicted_net_flow: number;
}

export interface DailyPrediction {
  community_id: number;
  series: PredictedFlowPoint[];
}

export interface TimeSeriesPoint {
  time_slot: string;        // ISO 字符串（后端不带Z，这里按字符串处理）
  borrow_count: number;
  return_count: number;
}

export interface CommunityTimeSeries {
  community_id: number;
  start_time: string;
  end_time: string;
  series: TimeSeriesPoint[];
}

export interface CommunityFlowStats {
  community_id: number;
  borrow_count: number;
  return_count: number;
  net_flow: number;
}

export interface FlowStatsData {
  start_slot: string;
  end_slot: string;
  stats: CommunityFlowStats[];
}

export interface ODPair {
  start_community_id: number;
  end_community_id: number;
  flow_count: number;
}

export interface ODData {
  start_slot: string;
  end_slot: string;
  od_pairs: ODPair[];
}

export interface WeatherInfo {
  wind_direction?: string | null;
  wind_speed?: string | null;
  temp_min?: number | null;
  temp_max?: number | null;
  humidity?: number | null;
  rain?: number | null;
  air_quality_index?: number | null;
  air_quality_level?: number | null;
}

export interface WeatherData {
  requested_time: string;
  record_time: string;
  weather: WeatherInfo;
}

export interface WeatherResponse {
  code: number;
  message: string;
  data: WeatherData | null;
}

// --- API 函数 ---

export const getCommunities = async (): Promise<CommunityGeo[]> => {
  try {
    const response = await fetch(`${API_BASE_URL}/communities`);
    if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
    const data = await response.json();
    return data.data;
  } catch (error) {
    console.error("Failed to fetch communities:", error);
    return [];
  }
};

export const getInitialBikeCounts = async (): Promise<Record<string, number>> => {
  try {
    // 从 public 目录获取静态 JSON 文件
    const response = await fetch('/initial_bike_counts.json');
    if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
    return await response.json();
  } catch (error) {
    console.error("Failed to fetch initial bike counts:", error);
    return {};
  }
};

export const getAllHistoricalFlows = async (): Promise<HistoricalFlow[]> => {
  try {
    const response = await fetch(`${API_BASE_URL}/statistics/historical-flows`);
    if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
    const data = await response.json();
    return data.data;
  } catch (error) {
    console.error("Failed to fetch all historical flows:", error);
    return [];
  }
};

export const getDailyPredictions = async (date: string): Promise<DailyPrediction[]> => {
  try {
    const response = await fetch(`${API_BASE_URL}/predictions/daily-netflow?query_date=${date}`);
    if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
    const data = await response.json();
    return data.data.predictions;
  } catch (error) {
    console.error(`Failed to fetch predictions for ${date}:`, error);
    return [];
  }
};

export const getCommunityTimeSeries = async (communityId: number, timeISO: string): Promise<CommunityTimeSeries | null> => {
  try {
    const resp = await fetch(`${API_BASE_URL}/statistics/timeseries/${communityId}?time=${encodeURIComponent(timeISO)}`);
    if (!resp.ok) throw new Error(`HTTP error! status: ${resp.status}`);
    const json = await resp.json();
    // 按后端 schemas 返回结构提取 data
    return json.data as CommunityTimeSeries;
  } catch (err) {
    console.error(`Failed to fetch time series for community ${communityId}:`, err);
    return null;
  }
};

export const getHistoricalFlow = async (timeISO: string): Promise<FlowStatsData | null> => {
  try {
    const resp = await fetch(`${API_BASE_URL}/statistics/flow?time=${encodeURIComponent(timeISO)}`);
    if (!resp.ok) throw new Error(`HTTP error! status: ${resp.status}`);
    const json = await resp.json();
    return json.data as FlowStatsData;
  } catch (err) {
    console.error('Failed to fetch historical flow:', err);
    return null;
  }
};

export const getODPairs = async (timeISO: string, minFlow: number = 1): Promise<ODData | null> => {
  try {
    const resp = await fetch(`${API_BASE_URL}/statistics/od?time=${encodeURIComponent(timeISO)}&min_flow=${minFlow}`);
    if (!resp.ok) throw new Error(`HTTP error! status: ${resp.status}`);
    const json = await resp.json();
    return json.data as ODData;
  } catch (err) {
    console.error('Failed to fetch OD pairs:', err);
    return null;
  }
};

export const getWeatherByTime = async (isoTime: string): Promise<WeatherData | null> => {
  try {
    const resp = await fetch(`${API_BASE_URL}/weather?time=${encodeURIComponent(isoTime)}`);
    if (resp.status === 404) {
      console.warn('Weather not found for', isoTime);
      return null;
    }
    if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
    const json: WeatherResponse = await resp.json();
    return json.data;
  } catch (e) {
    console.error('Failed to fetch weather:', e);
    return null;
  }
};